package com.borball.store.comp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Timestamp;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableRowSorter;

import com.borball.store.dao.CustomerMoneyDAO;
import com.borball.store.domain.CustomerMoney;
import com.borball.store.domain.User;

import craky.component.CommonTableModel;
import craky.componentc.JCButton;
import craky.componentc.JCLabel;
import craky.componentc.JCMessageBox;
import craky.componentc.JCPopupMenu;
import craky.componentc.JCScrollTable;
import craky.componentc.JCTable;
import craky.componentc.JCTableHeader;
import craky.componentc.JCTextField;
import craky.keeper.EmptyComponent;
import craky.keeper.KeeperApp;
import craky.keeper.KeeperPane;
import craky.layout.LineLayout;

public class CustomerMoneyPane extends KeeperPane {

	private static final long serialVersionUID = 2583431180094797757L;

	private static final String CMD_INSERT = "Insert";

	private static final String CMD_MODIFY = "Modify";

	private static final String[] COLUMNS_NAME = { "客户名称", "应收金额", "已经收回金额", "最近修改时间", "备注" };

	protected KeeperApp keeper;

	protected User currentUser;

	protected CommonTableModel<CustomerMoney> model;

	protected List<CustomerMoney> data;

	protected CustomerMoney currentData;

	protected Action insertAction, modifyAction, deleteAction, submitAction, cancelAction;

	protected JCTable table;

	protected JCPopupMenu popup;

	protected JComponent top, bottom, center;

	protected JComponent ecCustomer, ecAllmoney, ecReturnmoney, ecMemo;

	protected JCTextField cpCustomer, cpAllmoney, cpReturnmoney, cpMemo;

	private JCButton btnModify, btnDelete, btnInsert, btnSubmit, btnCancel;

	private boolean modifying;

	private int selectedIndex;
	private CustomerMoneyDAO dao;
	
	public CustomerMoneyPane(KeeperApp keeper) {
		dao = new CustomerMoneyDAO();
		this.keeper = keeper;
		this.currentUser = keeper.getCurrentUser();

		this.selectedIndex = -1;

		loadData();
		initActions();
		initUI();
	}

	private void initActions() {
		insertAction = new AbstractAction("\u6DFB\u52A0") {
			private static final long serialVersionUID = 5056698643009336063L;

			public void actionPerformed(ActionEvent e) {
				insertOrModify(true);
			}
		};

		modifyAction = new AbstractAction("\u4FEE\u6539") {
			private static final long serialVersionUID = 8222836515926767063L;

			public void actionPerformed(ActionEvent e) {
				insertOrModify(false);
			}
		};

		deleteAction = new AbstractAction("\u5220\u9664") {
			private static final long serialVersionUID = -4608405524916997614L;

			public void actionPerformed(ActionEvent e) {
				delete();
			}
		};

		submitAction = new AbstractAction("\u786E\u5B9A") {
			private static final long serialVersionUID = 6989199497316998154L;

			public void actionPerformed(ActionEvent e) {
				submit();
			}
		};

		cancelAction = new AbstractAction("\u53D6\u6D88") {
			private static final long serialVersionUID = 6989199497316998154L;

			public void actionPerformed(ActionEvent e) {
				cancel();
			}
		};

		modifyAction.setEnabled(false);
		deleteAction.setEnabled(false);
	}

	private void initUI() {
		btnModify = new JCButton(modifyAction);
		btnDelete = new JCButton(deleteAction);
		btnInsert = new JCButton(insertAction);
		btnSubmit = new JCButton(submitAction);
		btnCancel = new JCButton(cancelAction);
		btnModify.setPreferredSize(new Dimension(-1, 21));
		btnDelete.setPreferredSize(btnModify.getPreferredSize());
		btnInsert.setPreferredSize(btnModify.getPreferredSize());
		btnSubmit.setPreferredSize(btnModify.getPreferredSize());
		btnCancel.setPreferredSize(btnModify.getPreferredSize());
		btnSubmit.setVisible(false);
		btnCancel.setVisible(false);
		EmptyComponent centerParent = new EmptyComponent();
		setLayout(new BorderLayout());
		centerParent.setLayout(new BorderLayout(0, 3));
		createCenter();
		createBottom();

		this.add(centerParent, BorderLayout.CENTER);

		if (center != null) {
			centerParent.add(center, BorderLayout.CENTER);
		}

		if (top != null) {
			centerParent.add(top, BorderLayout.NORTH);
		}

		if (bottom != null) {
			centerParent.add(bottom, BorderLayout.SOUTH);
		}

	}

	protected void resetTypes() {

	}

	public void loadData() {
		data = dao.findAll();
	}
	
	public void reload(){
		loadData();
		model.refreshUI();
	}

	protected JComponent createBottom() {

		bottom = new EmptyComponent();
		bottom.setBorder(new CompoundBorder(new EmptyBorder(0, 0, 0, 0), new LineBorder(new Color(84, 165, 213))));
		bottom.setPreferredSize(new Dimension(-1, 77));
		bottom.setLayout(new BorderLayout());
		bottom.add(createDetailComponent(), BorderLayout.CENTER);

		EmptyComponent buttonContainer = new EmptyComponent();
		buttonContainer.setLayout(new LineLayout(3, 0, 5, 0, 3, LineLayout.TRAILING, LineLayout.TRAILING,
				LineLayout.VERTICAL));
		buttonContainer.setPreferredSize(new Dimension(85, -1));
		buttonContainer.add(btnSubmit, LineLayout.END_FILL);

		buttonContainer.add(btnDelete, LineLayout.END_FILL);
		buttonContainer.add(btnModify, LineLayout.END_FILL);

		buttonContainer.add(btnInsert, LineLayout.END_FILL);
		buttonContainer.add(btnCancel, LineLayout.END_FILL);
		bottom.add(buttonContainer, BorderLayout.EAST);

		return bottom;
	}

	protected JComponent createCenter() {
		final Class<?>[] columnsClass = { String.class, Float.class, Float.class, Timestamp.class, String.class };
		final String[] getMethodsName = { "getCustomer", "getAllmoney", "getReturnmoney", "getModified", "getMemo" };
		final String[] setMethodsName = { "setCustomer", "setAllmoney", "setReturnmoney", "setModified", "setMemo" };
		final int[] columnsPreferredWidth = { 100, 100, 100, 100, 200 };
		EmptyComponent ec = new EmptyComponent();
		JCScrollTable scTable = new JCScrollTable();
		table = scTable.getTable();
		model = new CommonTableModel<CustomerMoney>(table, COLUMNS_NAME, columnsClass, getMethodsName, setMethodsName, data);
		TableRowSorter<CommonTableModel<CustomerMoney>> sorter = new TableRowSorter<CommonTableModel<CustomerMoney>>(model);

		scTable.setAlpha(0.0f);
		scTable.setColumnControlEnabled(false);
		ec.setLayout(new BorderLayout());
		ec.add(scTable, BorderLayout.CENTER);
		table.setModel(model);
		table.setDragEnabled(false);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setRowSorter(sorter);
		table.setRendererOpaque(false);
		((JCTableHeader) table.getTableHeader()).setShowPopupMenu(false);
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				whenSelectionChanged(e);
			}
		});
		table.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				select(e);
			}

			public void mouseReleased(MouseEvent e) {
				showPopupMenu(e);
			}
		});

		for (int i = 0; i < columnsPreferredWidth.length; i++) {
			table.getColumnModel().getColumn(i).setPreferredWidth(columnsPreferredWidth[i]);
		}

		return center = ec;
	}

	private JComponent createDetailComponent() {
		EmptyComponent ec = new EmptyComponent();
		EmptyComponent firstRow = new EmptyComponent();

		JCLabel lbName = new JCLabel("客户名称");
		JCLabel lbAllmoney = new JCLabel("总金额");
		JCLabel lbReturnmoney = new JCLabel("已回收金额");
		JCLabel lbMemo = new JCLabel("其它备注");
		
		Border border = new EmptyBorder(0, 0, 0, 5);
		cpCustomer = new JCTextField();
		cpAllmoney = new JCTextField();
		cpReturnmoney = new JCTextField();
		cpMemo = new JCTextField();

		firstRow.setLayout(new BoxLayout(firstRow, BoxLayout.X_AXIS));
		firstRow.setPreferredSize(new Dimension(-1, 25));
		firstRow.add(ecCustomer = createTitledComponent(lbName, cpCustomer, border, 3));
		firstRow.add(ecAllmoney = createTitledComponent(lbAllmoney, cpAllmoney, border, 3));
		firstRow.add(ecReturnmoney = createTitledComponent(lbReturnmoney, cpReturnmoney, border, 3));

		EmptyComponent secondRow = new EmptyComponent();
		secondRow.setLayout(new GridLayout(1, 2));
		secondRow.add(ecMemo = createTitledComponent(lbMemo, cpMemo, border, 3));
		
		ec.setLayout(new BorderLayout(0, 5));
		ec.setBorder(new EmptyBorder(3, 5, 2, 2));
		ec.add(firstRow, BorderLayout.NORTH);
		ec.add(secondRow, BorderLayout.CENTER);
		
		ecCustomer.setPreferredSize(new Dimension(70, -1));
		ecAllmoney.setPreferredSize(new Dimension(200, -1));
		ecReturnmoney.setPreferredSize(new Dimension(140, -1));
		ecMemo.setPreferredSize(new Dimension(230, -1));
		
		resetTextStatus(false);
		
		return ec;
	}

	private JComponent createTitledComponent(JComponent titleComponent, JComponent component, Border border, int hgap) {
		EmptyComponent ec = new EmptyComponent();
		ec.setBorder(border);
		ec.setLayout(new BorderLayout(hgap, 0));
		ec.add(component, BorderLayout.CENTER);

		if (titleComponent != null) {
			ec.add(titleComponent, BorderLayout.WEST);
		}

		return ec;
	}

	private void resetDetailValues() {
		if (bottom.isVisible()) {
			if (currentData == null) {
				clearValues();
			} else {
				fillValues();
			}

			resetTextStatus(false);
			resetButtonStatus(false);
		}
	}

	private void clearValues() {
		 cpCustomer.setText(null);
		 cpAllmoney.setText(null);
		 cpReturnmoney.setText(null);
		 cpMemo.setText(null);
	}

	private void fillValues() {
		cpCustomer.setText(currentData.getCustomer());
		cpAllmoney.setText(String.valueOf((int)currentData.getAllmoney()));
		cpReturnmoney.setText(String.valueOf((int)currentData.getReturnmoney()));
		cpMemo.setText(currentData.getMemo().toString());
	}

	private void resetTextStatus(boolean editable) {
		 cpCustomer.setEditable(editable);
		 cpAllmoney.setEditable(editable);
		 cpReturnmoney.setEditable(editable);
		 cpMemo.setEditable(editable);
	}

	private void resetButtonStatus(boolean modifying) {
		this.modifying = modifying;
		btnSubmit.setVisible(modifying);
		btnCancel.setVisible(modifying);
		btnInsert.setVisible(!modifying);
		btnModify.setVisible(!modifying);
		btnDelete.setVisible(!modifying);
	}

	private void select(MouseEvent e) {
		int row = table.rowAtPoint(e.getPoint());

		if (row >= 0 && SwingUtilities.isRightMouseButton(e)) {
			table.getSelectionModel().setSelectionInterval(row, row);
		} else if (row < 0 && !SwingUtilities.isMiddleMouseButton(e)) {
			if (selectedIndex >= 0) {
				table.clearSelection();
			} else {
				resetDetailValues();
			}
		}
	}

	private void showPopupMenu(MouseEvent e) {
		if (popup != null && SwingUtilities.isRightMouseButton(e)) {
			popup.show((Component) e.getSource(), e.getX(), e.getY());
		}
	}

	private void whenSelectionChanged(ListSelectionEvent e) {
		currentData = table.getSelectedRow() < 0 ? null : model.getSelectedRowData();
		boolean selectedEmpty = (selectedIndex = table.getSelectedRow()) < 0;
		modifyAction.setEnabled(!selectedEmpty);
		deleteAction.setEnabled(!selectedEmpty);
		resetDetailValues();
	}

	protected void resetRowValues(CustomerMoney customer) {
		customer.setCustomer(cpCustomer.getText());
		customer.setAllmoney(Float.valueOf(cpAllmoney.getText()));
		customer.setReturnmoney(Float.valueOf(cpReturnmoney.getText()));
		customer.setMemo(cpMemo.getText());
	}

	public void cancel() {
		btnSubmit.setActionCommand(null);
		resetDetailValues();
	}

	protected boolean checkInput() {
		return true;
	}

	protected boolean checkFilter(User data) {
		return true;
	}

	public void submit() {
		if (!btnSubmit.isVisible() || !checkInput()) {
			return;
		}

		String cmd = btnSubmit.getActionCommand();
		boolean insert = true;
		CustomerMoney c = null; 
		
		if (CMD_INSERT.equals(cmd)) {
			c = new CustomerMoney();
			c.setCustomer(cpCustomer.getText());
			c.setAllmoney(Float.valueOf(cpAllmoney.getText()));
			c.setReturnmoney(Float.valueOf(cpReturnmoney.getText()));
			c.setMemo(cpMemo.getText());
			
		} else if (CMD_MODIFY.equals(cmd)) {
			c = currentData;
			insert = false;
		}

		resetRowValues(c);

		if (insert) {
			dao.add(c);
			
			model.insertRowData(c);
			int row = model.convertRowIndexesToView(model.getRowCount() - 1)[0];
			table.getSelectionModel().setSelectionInterval(row, row);
		} else {
			dao.update(c);
			
			model.refreshRowOnView(selectedIndex);
			fillValues();
		}

		resetButtonStatus(false);
		resetTextStatus(false);
		btnSubmit.setActionCommand(null);

	}

	public void insertOrModify(boolean insert) {
		if (modifying) {
			cancel();
		}

		btnSubmit.setActionCommand(insert ? CMD_INSERT : CMD_MODIFY);
		resetTextStatus(true);
		resetButtonStatus(true);

		if (insert) {
			clearValues();
			cpCustomer.requestFocus();
		}
	}

	public void delete() {
		String message = "\u786E\u5B9A\u8981\u5220\u9664\u8BE5\u8BB0\u5F55\u5417\uFF1F";
		JCMessageBox box = JCMessageBox.createQuestionMessageBox(keeper.getMainFrame(), "\u5220\u9664", message);

		if (box.open() == JCMessageBox.YES_OPTION) {
			dao.delete(currentData);
			model.delRowOnViewAt(selectedIndex);
		}
	}

	@Override
	public String getType() {
		return "客户管理";
	}

	@Override
	public void refresh() {
		loadData();
		model.delAllRow();
		model.setDataList(data);
		model.getTable().repaint();
		model.refreshRowOnView(0);
	}

}
